package com.smart.translator.util;

import android.util.Log;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.WebSocket;
import okhttp3.WebSocketListener;
import okio.ByteString;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
import android.os.Handler;
import android.os.Looper;
import java.util.HashMap;
import java.util.Map;

public class AliyunAsrClient {
    private static final String TAG = "AliyunAsrClient";
    
    // WebSocket配置
    private String wsUrl = "ws://localhost:8000/ws/aliyun_asr_v2"; // 默认使用本地测试服务器
    
    // 音频配置
    private String format = "pcm";
    private int rate = 8000;//16000; // 16kHz
    private int bits = 16;
    private int channel = 1;
    private String model = "paraformer-realtime-8k-v2";
    //"paraformer-realtime-v2";
    private String[] languageHints = {"zh", "en"};
    
    // WebSocket
    private WebSocket webSocket;
    private boolean isConnected = false;
    private AliyunAsrCallback callback;
    private boolean isRecognizing = false;
    private boolean hasError = false;
    
    // 音频数据缓冲
    private ByteArrayOutputStream audioBuffer = new ByteArrayOutputStream();
    private static final int CHUNK_SIZE = 3200; // 200ms的16kHz音频数据
    
    // 默认启用重采样
    private boolean enableResampling = true;
    private AudioResampler audioResampler;
    
    // 音频统计
    private long totalAudioBytes = 0;
    private int audioChunkCount = 0;

    private final ByteArrayOutputStream sendBuffer = new ByteArrayOutputStream();
    // 修改：使用后台线程的Handler，避免阻塞主线程
    private Handler sendHandler;
    private android.os.HandlerThread sendThread;
    private Runnable sendRunnable;
    private static final int SEND_CHUNK_SIZE = 3200; // 100ms 16k 16bit 1ch
    private static final int SEND_INTERVAL_MS = 100;
    private boolean sendLoopStarted = false;
    
    // 新增：线程安全的音频缓冲区
    private final Object sendBufferLock = new Object();
    
    // 新增：性能监控
    private long lastSendTime = 0;
    private int sendCount = 0;
    private long totalSendTime = 0;
    
    // 新增：直连阿里云官方API相关变量
    private boolean useAliyunDirect = true;
    private String aliyunApiKey = "sk-02e1be9ce510429d8c28950a27ac6957";
    private WebSocket aliyunDirectWebSocket;
    private boolean aliyunDirectTaskStarted = false;
    private String aliyunDirectTaskId = java.util.UUID.randomUUID().toString();
    private ByteArrayOutputStream aliyunDirectAudioBuffer = new ByteArrayOutputStream();
    
    // 新增：标记最后一包
    private volatile boolean pendingLastAudio = false;
    
    public interface AliyunAsrCallback {
        void onConnected();
        void onInitialRequestSent();
        void onMessage(String text, boolean isFinal);
        void onError(String error);
        void onClosed();
    }
    
    public AliyunAsrClient() {
        // 默认启用重采样
        enableResampling();
        // 初始化后台发送线程
        initSendThread();
    }
    
    public AliyunAsrClient(String wsUrl) {
        this.wsUrl = wsUrl;
        // 默认启用重采样
        enableResampling();
        // 初始化后台发送线程
        initSendThread();
    }
    
    public void setCallback(AliyunAsrCallback callback) {
        this.callback = callback;
    }
    
    /**
     * 设置WebSocket URL
     */
    public void setWebSocketUrl(String wsUrl) {
        this.wsUrl = wsUrl;
        Log.d(TAG, "设置WebSocket URL: " + this.wsUrl);
    }
    
    /**
     * 启用音频重采样（8kHz -> 16kHz）
     */
    public void enableResampling() {
        this.enableResampling = true;
        if (audioResampler == null) {
            audioResampler = new AudioResampler();
        }
        Log.d(TAG, "启用音频重采样");
    }
    
    /**
     * 禁用音频重采样
     */
    public void disableResampling() {
        this.enableResampling = false;
        Log.d(TAG, "禁用音频重采样");
    }
    
    /**
     * 设置音频配置
     */
    public void setAudioConfig(int sampleRate, int bits, int channels) {
        this.rate = sampleRate;
        this.bits = bits;
        this.channel = channels;
        Log.d(TAG, "设置音频配置: " + sampleRate + "Hz, " + bits + "bit, " + channels + "ch");
    }
    
    /**
     * 设置音频配置（简化版）
     */
    public void setAudioConfig(int sampleRate) {
        setAudioConfig(sampleRate, 16, 1);
    }
    
    /**
     * 设置识别模型
     */
    public void setModel(String model) {
        this.model = model;
        Log.d(TAG, "设置识别模型: " + model);
    }
    
    /**
     * 设置语言提示
     */
    public void setLanguageHints(String[] languageHints) {
        this.languageHints = languageHints;
        Log.d(TAG, "设置语言提示: " + Arrays.toString(languageHints));
    }
    
    /**
     * 获取音频统计信息
     */
    public String getAudioStats() {
        return "总音频字节: " + totalAudioBytes + ", 音频块数: " + audioChunkCount;
    }
    
    /**
     * 获取发送性能统计信息
     */
    public String getSendPerformanceStats() {
        if (sendCount > 0) {
            return "发送次数: " + sendCount + ", 平均处理时间: " + (totalSendTime / sendCount) + "ms, 总处理时间: " + totalSendTime + "ms";
        } else {
            return "暂无发送统计数据";
        }
    }
    
    /**
     * 设置是否使用直连阿里云官方API
     */
    public void setUseAliyunDirect(boolean useDirect) { this.useAliyunDirect = useDirect; }
    /**
     * 设置阿里云API密钥
     */
    public void setAliyunApiKey(String apiKey) { this.aliyunApiKey = apiKey; }
    /**
     * 获取是否使用直连阿里云官方API
     */
    public boolean isUseAliyunDirect() { return useAliyunDirect; }
    
    /**
     * 连接WebSocket
     */
    public void connect() {
        if (useAliyunDirect) {
            connectAliyunOfficial();
        } else {
            connectProxy();
        }
    }
    
    /**
     * 开始识别
     */
    public void startRecognition() {
        if (!isConnected) {
            Log.e(TAG, "WebSocket未连接，无法开始识别");
            return;
        }
        
        if (isRecognizing) {
            Log.d(TAG, "识别已在进行中，跳过重复开始");
            return;
        }
        
        try {
            // 构建开始识别请求
            JSONObject request = new JSONObject();
            request.put("type", "start");
            
            JSONObject config = new JSONObject();
            config.put("model", model);
            config.put("format", format);
            config.put("sample_rate", rate);
            config.put("language_hints", new org.json.JSONArray(Arrays.asList(languageHints)));
            
            request.put("config", config);
            
            String requestStr = request.toString();
            Log.d(TAG, "发送开始识别请求: " + requestStr);
            
            boolean sent = webSocket.send(requestStr);
            if (sent) {
                isRecognizing = true;
                Log.d(TAG, "开始识别请求发送成功");
                
                if (callback != null) {
                    callback.onInitialRequestSent();
                }
            } else {
                Log.e(TAG, "开始识别请求发送失败");
            }
            
        } catch (Exception e) {
            Log.e(TAG, "发送开始识别请求异常", e);
            if (callback != null) {
                callback.onError("发送开始识别请求异常: " + e.getMessage());
            }
        }
    }
    
    /**
     * 停止识别
     */
    public void stopRecognition() {
        if (useAliyunDirect) {
            if (aliyunDirectWebSocket != null && isConnected) {
                try {
                    org.json.JSONObject header = new org.json.JSONObject();
                    header.put("action", "finish-task");
                    header.put("task_id", aliyunDirectTaskId);
                    header.put("streaming", "duplex");
                    org.json.JSONObject payload = new org.json.JSONObject();
                    payload.put("input", new org.json.JSONObject());
                    org.json.JSONObject finishTask = new org.json.JSONObject();
                    finishTask.put("header", header);
                    finishTask.put("payload", payload);
                    aliyunDirectWebSocket.send(finishTask.toString());
                } catch (Exception e) {
                    Log.e(TAG, "Aliyun直连发送finish-task失败", e);
                }
            }
        } else {
            if (!isConnected || !isRecognizing) {
                Log.d(TAG, "WebSocket未连接或识别未开始，无法停止识别");
                return;
            }
            try {
                org.json.JSONObject request = new org.json.JSONObject();
                request.put("type", "stop");
                String requestStr = request.toString();
                Log.d(TAG, "发送停止识别请求: " + requestStr);
                boolean sent = webSocket.send(requestStr);
                if (sent) {
                    isRecognizing = false;
                    Log.d(TAG, "停止识别请求发送成功");
                } else {
                    Log.e(TAG, "停止识别请求发送失败");
                }
            } catch (Exception e) {
                Log.e(TAG, "发送停止识别请求异常", e);
            }
        }
    }
    
    /**
     * 外部调用：追加音频数据到缓冲区，由内部定时分包发送（自动重采样）
     */
    public void appendAudioData(byte[] audioData) {
        try {
            byte[] processedAudioData = audioData;
            if (enableResampling && audioResampler != null && rate == 16000) {
                try {
                    processedAudioData = audioResampler.resample8kTo16k(audioData);
                } catch (Exception e) {
                    Log.e(TAG, "重采样失败，使用原始数据", e);
                    processedAudioData = audioData;
                }
            }
            synchronized (sendBufferLock) {
                sendBuffer.write(processedAudioData);
            }
        } catch (IOException e) {
            Log.e(TAG, "音频数据写入缓冲区失败", e);
        }
    }

    /**
     * 启动定时分包发送音频数据
     */
    private void startSendLoop() {
        if (sendLoopStarted) return;
        sendLoopStarted = true;
        
        // 确保后台线程已初始化
        if (sendHandler == null) {
            initSendThread();
        }
        
        sendRunnable = new Runnable() {
            @Override
            public void run() {
                long startTime = System.currentTimeMillis();
                
                if (!(useAliyunDirect ? (isConnected && aliyunDirectTaskStarted) : (isConnected && isRecognizing))) {
                    sendLoopStarted = false;
                    return;
                }
                try {
                    byte[] buffer;
                    synchronized (sendBufferLock) {
                        buffer = sendBuffer.toByteArray();
                    }
                    int chunkSize = (rate == 8000) ? 1600 : 3200;
                    int sendLen = Math.min(buffer.length, chunkSize);
                    if (sendLen > 0) {
                        byte[] sendData = Arrays.copyOfRange(buffer, 0, sendLen);
                        if (useAliyunDirect) {
                            // 减少日志输出频率，只在调试时输出
                            //if (Log.isLoggable(TAG, Log.DEBUG)) 
                            {
                                Log.d(TAG, "Aliyun直连定时发送音频包: " + sendLen + " 字节");
                            }
                            final int MAX_RETRY = 3;
                            int retryCount = 0;
                            boolean sendOk = false;
                            while (retryCount < MAX_RETRY) {
                                sendOk = aliyunDirectWebSocket.send(okio.ByteString.of(sendData));
                                if (sendOk) break;
                                retryCount++;
                                Log.e(TAG, "❌ 发送音频包失败，重试第" + retryCount + "次，长度: " + sendData.length + " 字节");
                                try { Thread.sleep(30); } catch (InterruptedException e) { Thread.currentThread().interrupt(); }
                            }
                            if (!sendOk) {
                                Log.e(TAG, "❌ 发送音频包最终失败，已重试" + MAX_RETRY + "次，长度: " + sendData.length + " 字节");
                            }
                        } else {
                            sendAudioChunk(sendData, false);
                        }
                        // 移除已发送部分
                        synchronized (sendBufferLock) {
                            sendBuffer.reset();
                            if (buffer.length > sendLen) {
                                sendBuffer.write(buffer, sendLen, buffer.length - sendLen);
                            }
                        }
                        
                        // 性能监控
                        sendCount++;
                        long processTime = System.currentTimeMillis() - startTime;
                        totalSendTime += processTime;
                        if (sendCount % 100 == 0) { // 每100次输出一次统计
                            Log.d(TAG, "音频发送性能统计 - 平均处理时间: " + (totalSendTime / sendCount) + "ms, 总次数: " + sendCount);
                        }
                    } else if (pendingLastAudio && buffer.length > 0) {
                        // flush最后一包
                        if (useAliyunDirect) {
                            Log.d(TAG, "Aliyun直连定时发送最后音频包: " + buffer.length + " 字节");
                            aliyunDirectWebSocket.send(okio.ByteString.of(buffer));
                        } else {
                            sendAudioChunk(buffer, true);
                        }
                        synchronized (sendBufferLock) {
                            sendBuffer.reset();
                        }
                        pendingLastAudio = false;
                    }
                } catch (Exception e) {
                    Log.e(TAG, "定时发送音频数据异常", e);
                }
                sendHandler.postDelayed(this, SEND_INTERVAL_MS);
            }
        };
        sendHandler.postDelayed(sendRunnable, SEND_INTERVAL_MS);
    }

    /**
     * 停止定时发送并清空缓冲区
     */
    private void stopSendLoop() {
        sendLoopStarted = false;
        if (sendRunnable != null && sendHandler != null) {
            sendHandler.removeCallbacks(sendRunnable);
        }
        synchronized (sendBufferLock) {
            sendBuffer.reset();
        }
    }
    
    /**
     * 发送音频数据（最后一包时立即flush所有剩余数据）
     */
    public void sendAudioData(byte[] audioData, boolean isLast) {
        // 自动重采样8kHz PCM为16kHz PCM
        byte[] sendData = audioData;
        // try {
        //     if (enableResampling && audioResampler != null && rate == 16000 && audioData != null && audioData.length > 0) {
        //         if (audioData.length % 1600 == 0) {
        //             sendData = audioResampler.resample8kTo16k(audioData);
        //             Log.d(TAG, "sendAudioData: 自动重采样8kHz PCM为16kHz, 原始: " + audioData.length + " -> " + sendData.length);
        //         }
        //     }
        // } catch (Exception e) {
        //     Log.e(TAG, "sendAudioData: 重采样失败，使用原始数据", e);
        //     sendData = audioData;
        // }

        appendAudioData(sendData);
        if (isLast) {
            pendingLastAudio = true;
        }
    }
    
    /**
     * 发送音频块
     */
    private void sendAudioChunk(byte[] audioData, boolean isLast) {
        try {
            // 构建音频数据请求
            JSONObject request = new JSONObject();
            request.put("type", "audio");
            
            // Base64编码音频数据
            String base64Data = android.util.Base64.encodeToString(audioData, android.util.Base64.NO_WRAP);
            request.put("data", base64Data);
            
            String requestStr = request.toString();
            //Log.d(TAG, "发送音频数据: " + audioData.length + " 字节, isLast: " + isLast);
            
            boolean sent = webSocket.send(requestStr);
            if (sent) {
                audioChunkCount++;
                //Log.d(TAG, "音频数据发送成功，块数: " + audioChunkCount);
            } else {
                Log.e(TAG, "音频数据发送失败");
            }
            
        } catch (Exception e) {
            Log.e(TAG, "发送音频块异常", e);
        }
    }
    
    /**
     * 重置音频缓冲区
     */
    public void resetAudioBuffer() {
        audioBuffer.reset();
        totalAudioBytes = 0;
        audioChunkCount = 0;
        Log.d(TAG, "音频缓冲区已重置");
    }
    
    /**
     * 检查是否已连接
     */
    public boolean isConnected() {
        return isConnected && !hasError;
    }
    
    /**
     * 检查是否可以发送音频数据
     */
    public boolean canSendAudioData() {
        return isConnected() && isRecognizing;
    }
    
    /**
     * 关闭连接
     */
    public void close() {
        if (webSocket != null) {
            webSocket.close(1000, "正常关闭");
            webSocket = null;
        }
        isConnected = false;
        isRecognizing = false;
        hasError = false;
        stopSendLoop();
        
        // 清理后台发送线程
        if (sendThread != null) {
            try {
                sendThread.quitSafely();
                sendThread.join(1000); // 等待最多1秒
                sendThread = null;
                sendHandler = null;
                Log.d(TAG, "后台音频发送线程已清理");
            } catch (InterruptedException e) {
                Log.w(TAG, "等待发送线程退出时被中断", e);
                Thread.currentThread().interrupt();
            }
        }
        
        Log.d(TAG, "WebSocket连接已关闭");
    }
    
    /**
     * 处理文本消息
     */
    private void handleTextMessage(String text) {
        try {
            JSONObject json = new JSONObject(text);
            String type = json.optString("type");

            if ("result".equals(type)) {
                // 1. 先尝试顶层字段
                if (json.has("text") && json.has("sentence_end")) {
                    String resultText = json.optString("text", "");
                    boolean sentenceEnd = json.optBoolean("sentence_end", false);
                    Log.d(TAG, "识别结果: " + resultText + ", sentence_end: " + sentenceEnd + "（顶层）");
                    if (callback != null && sentenceEnd) {
                        Log.d(TAG, "即将回调callback.onMessage, text=" + resultText + ", isFinal=" + sentenceEnd);
                        callback.onMessage(resultText, sentenceEnd);
                        Log.d(TAG, "已回调callback.onMessage");
                    } else if (!sentenceEnd) {
                        Log.d(TAG, "忽略中间ASR结果: " + resultText);
                    }
                } else {
                    // 2. 兼容嵌套结构
                    JSONObject payload = json.optJSONObject("payload");
                    if (payload != null) {
                        JSONObject output = payload.optJSONObject("output");
                        if (output != null) {
                            JSONObject sentence = output.optJSONObject("sentence");
                            if (sentence != null) {
                                boolean sentenceEnd = sentence.optBoolean("sentence_end", false);
                                String resultText = sentence.optString("text", "");
                                Log.d(TAG, "识别结果: " + resultText + ", sentence_end: " + sentenceEnd + "（嵌套）");
                                if (callback != null && sentenceEnd) {
                                    Log.d(TAG, "即将回调callback.onMessage, text=" + resultText + ", isFinal=" + sentenceEnd);
                                    callback.onMessage(resultText, sentenceEnd);
                                    Log.d(TAG, "已回调callback.onMessage");
                                } else if (!sentenceEnd) {
                                    Log.d(TAG, "忽略中间ASR结果: " + resultText);
                                }
                            } else {
                                Log.w(TAG, "result消息中未找到sentence字段: " + text);
                            }
                        } else {
                            Log.w(TAG, "result消息中未找到output字段: " + text);
                        }
                    } else {
                        Log.w(TAG, "result消息中未找到payload字段: " + text);
                    }
                }
            } else if ("stopped".equals(type)) {
                Log.d(TAG, "识别已停止");
                isRecognizing = false;
            } else if ("error".equals(type)) {
                String errorMessage = json.optString("message", "未知错误");
                Log.e(TAG, "识别错误: " + errorMessage);
                if (callback != null) {
                    callback.onError("识别错误: " + errorMessage);
                }
            } else if ("pong".equals(type)) {
                Log.d(TAG, "收到心跳响应");
            } else {
                Log.d(TAG, "收到未知消息类型: " + type + ", 内容: " + text);
            }
        } catch (JSONException e) {
            Log.e(TAG, "解析消息JSON失败, 原始内容: " + text, e);
        }
    }
    
    /**
     * 处理二进制消息
     */
    private void handleBinaryMessage(byte[] data) {
        Log.d(TAG, "收到二进制消息: " + data.length + " 字节");
        // 通常不会收到二进制消息
    }

    // 直连阿里云官方API的实现
    private void connectAliyunOfficial() {
        String wsUrl = "wss://dashscope.aliyuncs.com/api-ws/v1/inference";
        Log.d(TAG, "Aliyun直连模式，准备连接官方WebSocket: " + wsUrl);
        Log.d(TAG, "Aliyun直连模式，使用API Key(前6): " + (aliyunApiKey != null && aliyunApiKey.length() > 6 ? aliyunApiKey.substring(0, 6) : "null"));
        OkHttpClient client = new OkHttpClient.Builder()
                .connectTimeout(10, TimeUnit.SECONDS)
                .readTimeout(30, TimeUnit.SECONDS)
                .writeTimeout(30, TimeUnit.SECONDS)
                .build();
        Request request = new Request.Builder()
                .url(wsUrl)
                .addHeader("Authorization", "bearer " + aliyunApiKey)
                .addHeader("user-agent", "fastapi-ota-demo")
                .build();
        aliyunDirectWebSocket = client.newWebSocket(request, new WebSocketListener() {
            @Override
            public void onOpen(WebSocket webSocket, Response response) {
                Log.d(TAG, "Aliyun直连WebSocket已打开");
                isConnected = true;
                hasError = false;
                aliyunDirectTaskStarted = false;
                if (callback != null) callback.onConnected();
                sendAliyunRunTask(webSocket);
            }
            @Override
            public void onMessage(WebSocket webSocket, String text) {
                Log.d(TAG, "Aliyun收到消息: " + text);
                handleAliyunDirectTextMessage(webSocket, text);
            }
            @Override
            public void onMessage(WebSocket webSocket, ByteString bytes) {
                Log.d(TAG, "Aliyun收到二进制消息: " + bytes.size() + " 字节");
            }
            @Override
            public void onClosed(WebSocket webSocket, int code, String reason) {
                Log.d(TAG, "Aliyun直连WebSocket已关闭: code=" + code + ", reason=" + reason);
                isConnected = false;
                if (callback != null) callback.onClosed();
            }
            @Override
            public void onFailure(WebSocket webSocket, Throwable t, Response response) {
                Log.e(TAG, "Aliyun直连WebSocket连接失败", t);
                isConnected = false;
                hasError = true;
                if (callback != null) callback.onError("Aliyun直连失败: " + t.getMessage());
            }
        });
    }
    private void sendAliyunRunTask(WebSocket webSocket) {
        try {
            String taskId = aliyunDirectTaskId;
            org.json.JSONObject header = new org.json.JSONObject();
            header.put("action", "run-task");
            header.put("task_id", taskId);
            header.put("streaming", "duplex");
            org.json.JSONObject parameters = new org.json.JSONObject();
            parameters.put("sample_rate", rate);
            parameters.put("format", format);
            parameters.put("heartbeat", true);
            
            if ("paraformer-realtime-v2".equals(model) && languageHints != null) {
                parameters.put("language_hints", new org.json.JSONArray(Arrays.asList(languageHints)));
            }
            org.json.JSONObject payload = new org.json.JSONObject();
            payload.put("task_group", "audio");
            payload.put("task", "asr");
            payload.put("function", "recognition");
            payload.put("model", model);
            payload.put("parameters", parameters);
            payload.put("input", new org.json.JSONObject());
            org.json.JSONObject runTask = new org.json.JSONObject();
            runTask.put("header", header);
            runTask.put("payload", payload);
            Log.d(TAG, "Aliyun直连发送run-task指令: " + runTask.toString());
            webSocket.send(runTask.toString());
            if (callback != null) callback.onInitialRequestSent();
        } catch (Exception e) {
            Log.e(TAG, "发送run-task指令失败", e);
        }
    }
    private void handleAliyunDirectTextMessage(WebSocket webSocket, String text) {
        try {
            org.json.JSONObject json = new org.json.JSONObject(text);
            org.json.JSONObject header = json.optJSONObject("header");
            if (header == null) return;
            String event = header.optString("event");
            if ("task-started".equals(event)) {
                aliyunDirectTaskStarted = true;
                Log.d(TAG, "Aliyun直连: 识别任务已开始，可以发送音频数据");
                // 新增：收到task-started时回调onInitialRequestSent
                if (callback != null) callback.onInitialRequestSent();
                // 新增：收到task-started时启动音频分包发送定时任务
                startSendLoop();
            } else if ("result-generated".equals(event)) {
                org.json.JSONObject payload = json.optJSONObject("payload");
                if (payload != null) {
                    org.json.JSONObject output = payload.optJSONObject("output");
                    if (output != null) {
                        org.json.JSONObject sentence = output.optJSONObject("sentence");
                        if (sentence != null) {
                            String resultText = sentence.optString("text", "");
                            boolean sentenceEnd = sentence.optBoolean("sentence_end", false);
                            if (callback != null && sentenceEnd) {
                                callback.onMessage(resultText, true);
                            }
                        }
                    }
                }
            } else if ("task-finished".equals(event)) {
                Log.d(TAG, "Aliyun直连: 识别任务完成");
            } else if ("task-failed".equals(event)) {
                String errorMsg = header.optString("error_message", "未知错误");
                if (callback != null) callback.onError("Aliyun直连失败: " + errorMsg);
            }
        } catch (Exception e) {
            Log.e(TAG, "Aliyun直连消息解析失败", e);
        }
    }
    private void connectProxy() {
        // 保持原有代理服务器连接逻辑
        if (isConnected) {
            Log.d(TAG, "WebSocket已连接，跳过重复连接");
            return;
        }
        
        try {
            Log.d(TAG, "正在连接WebSocket: " + wsUrl);
            
            OkHttpClient client = new OkHttpClient.Builder()
                    .connectTimeout(10, TimeUnit.SECONDS)
                    .readTimeout(30, TimeUnit.SECONDS)
                    .writeTimeout(30, TimeUnit.SECONDS)
                    .build();
            
            Request request = new Request.Builder()
                    .url(wsUrl)
                    .build();
            
            webSocket = client.newWebSocket(request, new WebSocketListener() {
                @Override
                public void onOpen(WebSocket webSocket, Response response) {
                    Log.d(TAG, "阿里云ASR WebSocket连接成功");
                    isConnected = true;
                    hasError = false;
                    
                    if (callback != null) {
                        callback.onConnected();
                    }
                    startSendLoop();
                }
                
                @Override
                public void onMessage(WebSocket webSocket, String text) {
                    Log.d(TAG, "收到文本消息: " + text);
                    handleTextMessage(text);
                }
                
                @Override
                public void onMessage(WebSocket webSocket, ByteString bytes) {
                    Log.d(TAG, "收到二进制消息: " + bytes.size() + " 字节");
                    handleBinaryMessage(bytes.toByteArray());
                }
                
                @Override
                public void onClosing(WebSocket webSocket, int code, String reason) {
                    Log.d(TAG, "WebSocket正在关闭: " + code + " - " + reason);
                }
                
                @Override
                public void onClosed(WebSocket webSocket, int code, String reason) {
                    Log.d(TAG, "WebSocket连接关闭: " + code + " - " + reason);
                    isConnected = false;
                    isRecognizing = false;
                    
                    if (callback != null) {
                        callback.onClosed();
                    }
                    stopSendLoop();
                }
                
                @Override
                public void onFailure(WebSocket webSocket, Throwable t, Response response) {
                    Log.e(TAG, "WebSocket连接失败", t);
                    isConnected = false;
                    hasError = true;
                    
                    if (callback != null) {
                        callback.onError("连接失败: " + t.getMessage());
                    }
                }
            });
            
        } catch (Exception e) {
            Log.e(TAG, "创建WebSocket连接异常", e);
            hasError = true;
            if (callback != null) {
                callback.onError("创建连接异常: " + e.getMessage());
            }
        }
    }
    private String bytesPreview(byte[] data, int offset) {
        if (data == null || data.length - offset < 4) return "null";
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < 4; i++) sb.append(String.format("%02X ", data[offset + i]));
        return sb.toString();
    }
    private void sendAliyunFinishTask() {
        try {
            org.json.JSONObject header = new org.json.JSONObject();
            header.put("action", "finish-task");
            header.put("task_id", aliyunDirectTaskId);
            header.put("streaming", "duplex");
            org.json.JSONObject payload = new org.json.JSONObject();
            payload.put("input", new org.json.JSONObject());
            org.json.JSONObject finishTask = new org.json.JSONObject();
            finishTask.put("header", header);
            finishTask.put("payload", payload);
            Log.d(TAG, "Aliyun直连发送finish-task指令: " + finishTask.toString());
            aliyunDirectWebSocket.send(finishTask.toString());
        } catch (Exception e) {
            Log.e(TAG, "Aliyun直连发送finish-task失败", e);
        }
    }

    /**
     * 初始化后台发送线程
     */
    private void initSendThread() {
        if (sendThread == null) {
            sendThread = new android.os.HandlerThread("AliyunAsrSendThread");
            sendThread.start();
            sendHandler = new Handler(sendThread.getLooper());
            Log.d(TAG, "后台音频发送线程已初始化");
        }
    }
} 